package com.alibaba.cirtus.ots.application.adapter.ability.facade.serviceV2.rpa;

import com.alibaba.citrus.ots.common.annotation.ProcessInvoker;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.lattice2.epoch.middleware.cache.runtime.service.EpochCacheService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.crunifiedinventory.inventoryverify.service.InventoryVerifyService;
import com.epoch.app.crunifiedinventory.model.dto.InventoryVerifyResponse;
import com.epoch.app.crunifiedinventory.model.dto.StandardInventoryFlagLoadListRequest;
import com.epoch.app.crunifiedinventory.standardinventoryflag.dto.DeleteRequest;
import com.epoch.app.crunifiedinventory.standardinventoryflag.model.StandardInventoryFlag;
import com.epoch.app.crunifiedinventory.standardinventoryflag.service.StandardInventoryFlagService;
import com.epoch.app.otsapplicationadaptersdk.model.dto.RPAInventoryVerifyRequest;
import com.epoch.app.otsapplicationadaptersdk.rpainventoryverify.service.RPAInventoryVerifyService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @description: RPA库存对账
 * @author: yuhw
 * @date: 2022年11月24日 16:32
 **/
@Component
@Primary
public class RPAInventoryVerifyServiceImpl implements RPAInventoryVerifyService {

    private static final Log log = Log.getLogger(RPAInventoryVerifyServiceImpl.class);

    @Resource
    private EpochCacheService epochCacheService;
    @Resource
    private StandardInventoryFlagService standardInventoryFlagService;
    @Resource
    private InventoryVerifyService inventoryVerifyService;

    private static final String LOCK_KEY = "RPAInventoryVerifyServiceImpl";
    private static final Integer MAX_PAGE_SIZE = 1000;


    @Override
    @ProcessInvoker(remark = "RPAInventoryVerifyServiceImpl", errorCode = "OTS-02-007-00-16-999", printLog = true)
    public Result<Void> verify(RPAInventoryVerifyRequest rpaInventoryVerifyRequest) {
        //查询RPA同步标记是否存在
        //设置锁 过期时间
        //对账
        //删除RPA同步标记
        //TODO 暂时去掉时间限制
        if (!timeInRange() && !Objects.equals(Boolean.TRUE,rpaInventoryVerifyRequest.getSkipTimeLimit())){
            return Result.fail("OTS-03-005-00-15-173","RPA对账不在对账时间范围内");
        }
        StandardInventoryFlagLoadListRequest request = new StandardInventoryFlagLoadListRequest();
        request.setLimit(MAX_PAGE_SIZE);
        Result<List<StandardInventoryFlag>> listResult = standardInventoryFlagService.loadList(request);
        if (listResult == null || CollectionUtils.isEmpty(listResult.getResult())){
            log.error("RPAInventoryVerifyServiceImpl_verify_syncNotCompleted");
            return Result.fail("OTS-03-005-00-15-174","RPA库存数据还未同步完成");
        }

        boolean lock = epochCacheService.setIfAbsent(BcOtsConstants.REDIS_CACHE_CODE(), LOCK_KEY, String.valueOf(System.currentTimeMillis()));
        if (!lock){
            log.error("RPAInventoryVerifyServiceImpl_verify_isRunning");
            return Result.fail("OTS-03-005-00-15-171","正在进行RPA对账,请等待执行完毕");
        }
        boolean expire = epochCacheService.expire(BcOtsConstants.REDIS_CACHE_CODE(), LOCK_KEY, 5 * 60 * 60, TimeUnit.SECONDS);
        if (!expire){
            log.error("RPAInventoryVerifyServiceImpl_verify_setExpireFailed");
            return Result.fail("OTS-03-005-00-15-172","RPA对账设置过期时间失败");
        }
        try{
            StopWatch stopWatch = new StopWatch("rpa_verify");
            // 取所有商品信息
            stopWatch.start("rpa_verify");
            Result<InventoryVerifyResponse> verify = inventoryVerifyService.verify();
            log.info("ots_rpa_verify_res:{}", JSON.toJSONString(verify));
            stopWatch.stop();
        }catch (Throwable e){
            log.error("RPAInventoryVerifyServiceImpl_verify_error",e);
        }finally {
            //释放锁
            epochCacheService.remove(BcOtsConstants.REDIS_CACHE_CODE(), Lists.newArrayList(LOCK_KEY));
        }

        //删除标记
        listResult.getResult().forEach(standardInventoryFlag -> {
            DeleteRequest deleteRequest = new DeleteRequest();
            deleteRequest.setId(standardInventoryFlag.getId());
            standardInventoryFlagService.delete(deleteRequest);
        });
        return Result.success(null);
    }

    /** 定时器运行时间 TODO 可以配置  **/
    private boolean timeInRange(){
        Date now = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MILLISECOND,0);

        Calendar endCalendar = Calendar.getInstance();
        endCalendar.set(Calendar.HOUR_OF_DAY,6);
        endCalendar.set(Calendar.MINUTE,0);
        endCalendar.set(Calendar.SECOND,0);
        endCalendar.set(Calendar.MILLISECOND,0);
        return now.after(calendar.getTime()) && now.before(endCalendar.getTime());
    }

}
